package logic

import (
	"ETikTok/dao/mysql"
	"ETikTok/dao/redis"
	"ETikTok/models"
	"ETikTok/pkg/snowflake"
	"go.uber.org/zap"
)

// CreateVideo 创建帖子
func CreateVideo(p *models.Video) (err error) {
	// 1. 生成video id
	p.ID = snowflake.GetID()
	// 2. 保存到数据库
	err = mysql.CreateVideo(p)
	if err != nil {
		zap.L().Error("mysql.CreateVideo() failed", zap.Error(err))
		return
	}
	err = redis.CreateVideo(p.ID, p.TagID)
	return
}

// GetVideoById 根据帖子ID查询帖子详情
func GetVideoById(pid int64) (data *models.ApiVideoDetail, err error) {
	// 查询并组合我们接口想要的数据
	video, err := mysql.GetVideoById(pid)
	if err != nil {
		zap.L().Error("mysql.GetVideoById failed", zap.Int64("pid", pid), zap.Error(err))
		return
	}

	// 根据作者ID查询作者信息
	user, err := mysql.GetUserById(video.AuthorID)
	if err != nil {
		zap.L().Error("mysql.GetUserById failed", zap.Int64("author_id", video.AuthorID), zap.Error(err))
		return
	}

	// 根据社区ID查询社区信息
	tag, err := mysql.GetTagDetailByID(video.TagID)
	if err != nil {
		zap.L().Error("mysql.GetTagDetailByID failed", zap.Int64("tag_id", video.TagID), zap.Error(err))
		return
	}

	// 接口数据拼接
	data = &models.ApiVideoDetail{
		AuthorName: user.Username,
		Video:      video,
		TagDetail:  tag,
	}

	return
}

// GetVideoList 获取帖子列表
func GetVideoList(page, size int64) (data []*models.ApiVideoDetail, err error) {
	videos, err := mysql.GetVideoList(page, size)
	if err != nil {
		zap.L().Error("mysql.GetVideoList failed", zap.Error(err))
		return nil, err
	}
	data = make([]*models.ApiVideoDetail, 0, len(videos))
	for _, video := range videos {
		// 根据作者ID查询作者信息
		user, err := mysql.GetUserById(video.AuthorID)
		if err != nil {
			zap.L().Error("mysql.GetUserById failed", zap.Int64("author_id", video.AuthorID), zap.Error(err))
			continue
		}
		// 根据社区ID查询社区信息
		tag, err := mysql.GetTagDetailByID(video.TagID)
		if err != nil {
			zap.L().Error("mysql.GetTagDetailByID failed", zap.Int64("tag_id", video.TagID), zap.Error(err))
			continue
		}

		// 接口数据拼接
		videoDetail := &models.ApiVideoDetail{
			AuthorName: user.Username,
			Video:      video,
			TagDetail:  tag,
		}

		data = append(data, videoDetail)
	}
	return
}

// GetVideoList2 获取帖子列表升级版
func GetVideoList2(p *models.ParamVideoList) (data []*models.ApiVideoDetail, err error) {
	// 根据前端传来的参数动态获得帖子列表（按分数、按时间）
	// 1.获取分页参数
	// 2.去redis查询获取id列表
	// 3.根据id去mysql查询帖子的详细信息
	ids, err := redis.GetVideoIDsInOrder(p)
	if err != nil {
		zap.L().Error("redis.GetVideoIDsInOrder failed", zap.Error(err))
		return
	}
	if len(ids) == 0 {
		zap.L().Warn("redis.GetVideoIDsInOrder return 0 data")
		return
	}
	videos, err := mysql.GetVideoListByIDs(ids)
	if err != nil {
		zap.L().Error("mysql.GetVideoListByIDs failed", zap.Error(err))
		return
	}
	// 根据ids提前查询好每篇帖子的投票数
	voteData, err := redis.GetVideoVoteData(ids)
	if err != nil {
		return
	}

	data = make([]*models.ApiVideoDetail, 0, len(videos))
	for idx, video := range videos {
		// 根据作者ID查询作者信息
		user, err := mysql.GetUserById(video.AuthorID)
		if err != nil {
			zap.L().Error("mysql.GetUserById failed", zap.Int64("author_id", video.AuthorID), zap.Error(err))
			continue
		}
		// 根据社区ID查询社区信息
		tag, err := mysql.GetTagDetailByID(video.TagID)
		if err != nil {
			zap.L().Error("mysql.GetTagDetailByID failed", zap.Int64("tag_id", video.TagID), zap.Error(err))
			continue
		}

		// 接口数据拼接
		videoDetail := &models.ApiVideoDetail{
			VoteNum:    voteData[idx],
			AuthorName: user.Username,
			Video:      video,
			TagDetail:  tag,
		}

		data = append(data, videoDetail)
	}
	return
}

func GetTagVideoList(p *models.ParamVideoList) (data []*models.ApiVideoDetail, err error) {
	// 根据前端传来的参数动态获得帖子列表（按分数、按时间）
	// 1.获取分页参数
	// 2.去redis查询获取id列表
	// 3.根据id去mysql查询帖子的详细信息
	ids, err := redis.GetTagVideoIDsInOrder(p)
	if err != nil {
		zap.L().Error("redis.GetVideoIDsInOrder failed", zap.Error(err))
		return
	}
	if len(ids) == 0 {
		zap.L().Warn("redis.GetVideoIDsInOrder return 0 data")
		return
	}
	videos, err := mysql.GetVideoListByIDs(ids)
	if err != nil {
		zap.L().Error("mysql.GetVideoListByIDs failed", zap.Error(err))
		return
	}
	// 根据ids提前查询好每篇帖子的投票数
	voteData, err := redis.GetVideoVoteData(ids)
	if err != nil {
		return
	}

	data = make([]*models.ApiVideoDetail, 0, len(videos))
	for idx, video := range videos {
		// 根据作者ID查询作者信息
		user, err := mysql.GetUserById(video.AuthorID)
		if err != nil {
			zap.L().Error("mysql.GetUserById failed", zap.Int64("author_id", video.AuthorID), zap.Error(err))
			continue
		}
		// 根据社区ID查询社区信息
		tag, err := mysql.GetTagDetailByID(video.TagID)
		if err != nil {
			zap.L().Error("mysql.GetTagDetailByID failed", zap.Int64("tag_id", video.TagID), zap.Error(err))
			continue
		}

		// 接口数据拼接
		videoDetail := &models.ApiVideoDetail{
			VoteNum:    voteData[idx],
			AuthorName: user.Username,
			Video:      video,
			TagDetail:  tag,
		}

		data = append(data, videoDetail)
	}
	return
}

// GetVideoListNew 获取帖子列表(将两个查询逻辑合并)
func GetVideoListNew(p *models.ParamVideoList) (data []*models.ApiVideoDetail, err error) {
	if p.TagID == 0 {
		// 查询所有的帖子
		data, err = GetVideoList2(p)
	} else {
		// 查询社区的帖子
		data, err = GetTagVideoList(p)
	}
	if err != nil {
		zap.L().Error("GetVideoListNew failed", zap.Error(err))
		return
	}
	return
}
